<template>
  <div class="draw-area">
    <div class="draw" :style="{height:paperSize[0]+'mm',width:paperSize[1]+'mm'}">
      <div class="details">
        <el-button size="mini" icon="el-icon-arrow-left" @click="pdfPage--" :disabled="pdfPage===1"></el-button>
        <span style="line-height: 27px">{{ pdfPage }}/{{ totalPage }}</span>
        <el-button size="mini" icon="el-icon-arrow-right" @click="pdfPage++"
                   :disabled="pdfPage===totalPage"></el-button>
      </div>
      <canvas id="canvas" :width="width" :height="height" style="z-index: 999"></canvas>
      <pdf style="position: absolute;left: 0;top: 0;"
           :style="{height:paperSize[0]+'mm',width:paperSize[1]+'mm'}"
           id="IMG"
           @num-pages="totalPage = $event"
           :src="pdfLink?pdfLink:''"
           :page="pdfPage">
      </pdf>
    </div>

    <div class="model" v-if="disabled"></div>
  </div>
</template>
<script>
import {fabric} from "fabric"
import pdf from "vue-pdf"

export default {
  name: "codeCanvas",
  props: {
    imgUrl: {
      type: String,
      default: () => "https://t7.baidu.com/it/u=1956604245,3662848045&fm=193&f=GIF"
    },
    pdfLink: {
      type: String,
      default: () => ""
    },
    canvasList: {
      type: Array,
      default: () => []
    },
    errorFun: Function,
    disabled: {
      type: Boolean,
      default: () => false
    },
    limit: {
      type: Number,
      default: () => 9999
    },
    addToAttr: {
      type: Object,
      default: () => ({})
    },
    paperSize: {
      type: Array,
      default: () => []
    },
  },
  components: {pdf},
  data() {
    return {
      canvas: null,
      rectList: [],

      width: 0,
      height: 0,

      select: true,

      disabledDraw: false,

      pdfPage: 1,
      totalPage: 0,
    };
  },
  mounted() {
    setTimeout(() => {
      let canvas = document.getElementById("canvas")
      let img = document.querySelector("#IMG");
      canvas.width = img.clientWidth;
      canvas.height = img.clientHeight;
      this.init()
    }, 500)
  },
  methods: {
    init() {
      this.canvas = new fabric.Canvas("canvas", {
        backgroundColor: "rgba(0,0,0,0)", // 画布背景色
        selectionColor: "rgba(0,0,0,.3)", // 画布中鼠标框选背景色
        selectionLineWidth: 0, // 画布中鼠标框选边框
        // selection: false, // 在画布中鼠标是否可以框选 默认为true
      });
      this.initEvent();
    },
    initEvent() {
      let down = {};
      this.canvas.on('mouse:down', (opt) => {
        down = opt;
        if (!!opt.target) {
          this.$emit("selectedItem", opt)
        } else {
          this.$emit("selectedItem", {})
        }
      });
      this.canvas.on('mouse:up', (opt) => {
        if (this.select) {
          if (opt.pointer.x - down.pointer.x === 0 || opt.pointer.y - down.pointer.y === 0) {
            return;
          }
          if (this.disabledDraw) {
            this.errorFun();
            return;
          }
          if (this.limit === this.rectList.length) {
            this.errorFun("limit");
            return;
          }
          let onlyId = this.getOnlyId();
          let rect = new fabric.Rect({
            top: down.pointer.y,
            left: down.pointer.x,
            width: opt.pointer.x - down.pointer.x,
            height: opt.pointer.y - down.pointer.y,
            fill: "rgba(255, 255, 255, 0)",
            stroke: '#000', // 边框原色
            strokeWidth: 1, // 边框大小
            selectable: true, // 是否允许当前对象被选中
            lockRotation: true, // 不允许旋转
          });
          //为每一个框添加专属ID
          Object.assign(rect, {SELF_OID: onlyId})

          //收集所有画出来的框
          let obj = {
            x: down.pointer.x,
            y: down.pointer.y,
            width: opt.pointer.x - down.pointer.x,
            height: opt.pointer.y - down.pointer.y,
            SELF_OID: onlyId,
            ...this.addToAttr
          }
          this.update_add(obj);

          this.canvas.add(rect);
          this.rectList.push(rect);
        }
        this.select = true;
      });

      this.canvas.on("object:moving", (opt) => {
        this.change_item(opt);
      })
      this.canvas.on("object:scaling", (opt) => {
        this.change_item(opt);
      })
    },
    change_item(opt) {
      let {target} = opt;
      let index = -1;
      let canvasList = this.deepCopy(this.canvasList);

      for (let i = 0; i < this.canvasList.length; i++) {
        let item = this.canvasList[i];
        if (item.SELF_OID === target.SELF_OID) {
          index = i;
        }
      }
      if (index !== -1) {
        Object.assign(canvasList[index], {
          x: target.left,
          y: target.top,
          width: target.width * target.scaleX,
          height: target.height * target.scaleY
        })
        this.$emit("update:canvasList", canvasList)
      }
      this.select = false;
    },
    update_add(obj) {
      let canvasList = this.deepCopy(this.canvasList);
      canvasList.push(obj);
      this.$emit("update:canvasList", canvasList)
    },
    clear_canvas() {
      this.rectList.forEach(rect => {
        this.canvas.remove(rect);
      })
      this.rectList = [];
    },
    remove_item(obj) {
      let rect = this.rectList.filter(i => i.SELF_OID === obj.SELF_OID)[0];
      this.rectList = this.rectList.filter(i => i.SELF_OID !== obj.SELF_OID);
      this.canvas.remove(rect);
    },
    ms$set(key, value) {
      this.$set(this, key, value);
    },
    refresh_canvas(list = []) {
      let val = list.length > 0 ? list : this.deepCopy(this.canvasList);
      this.clear_canvas();
      this.$nextTick(() => {
        if (val && val.length > 0) {
          this.rectList = [];
          val.forEach(item => {
            let rect = new fabric.Rect({
              top: item.y,
              left: item.x,
              width: item.width,
              height: item.height,
              fill: "rgba(255, 255, 255, 0)",
              stroke: '#000', // 边框原色
              strokeWidth: 1, // 边框大小
              selectable: true, // 是否允许当前对象被选中
              lockRotation: true, // 不允许旋转
            });
            Object.assign(rect, {SELF_OID: item.SELF_OID})
            this.canvas.add(rect);
            this.rectList.push(rect);
          })
        }
      })
    }
  }
};
</script>
<style scoped lang="scss">

.draw-area {
  width: 100%;

  .draw {
    position: relative;
    margin: auto;
    border: 1px solid #000000;
    overflow: hidden;
  }

  .details {
    position: absolute;
    top: 10px;
    left: 0;
    width: 100%;
    height: 30px;
    z-index: 99999;
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    flex-wrap: nowrap;
    box-sizing: border-box;
    padding:0 15px;
  }

  .IMG {
    width: 100%;
    position: absolute;
    top: 0;
    left: 0;
    z-index: -10;
  }

  .model {
    width: 100%;
    height: 100%;
    position: absolute;
    z-index: 9999;
    left: 0;
    top: 0;
  }
}
</style>
